package com.feonix.common.basedao;

import java.util.HashMap;
import java.util.Map;

import com.feonix.common.exception.SqlInjectionException;
import com.feonix.common.util.SqlUtil;
import com.feonix.common.util.StringUtil;
import com.feonix.common.util.jdbc.SqlLimitFactory;

public class Query {
	private Map<String, Object> params = new HashMap<String, Object>();
	private Integer pageNo;
	private Integer pageSize;
	private Integer start;
	private Integer end;
	private String sql = null;
	private SqlLimitFactory sqlLimitFactory;
	private boolean safeCheck = true;

	Query(String sql, SqlLimitFactory sqlLimitFactory) {
		this.sql = sql;
		this.sqlLimitFactory = sqlLimitFactory;
	}

	public Query addParameter(String name, Object value) {
		if (StringUtil.isNotEmpty(name)) {
			this.params.put(name, value);
		}
		return this;
	}

	public Query addParameter(String name, String value, LikeType likeType) {
		addParameter(name, SqlUtil.getLikeValue(value, likeType));
		return this;
	}

	public Query addParameters(Map<String, Object> parameters) {
		if (parameters != null) {
			this.params.putAll(parameters);
		}
		return this;
	}

	public void setSql(String sql) {
		this.sql = sql;
	}

	public Query setPageNo(Integer pageNo) {
		this.pageNo = pageNo;
		return this;
	}

	public Query setPageSize(Integer pageSize) {
		this.pageSize = pageSize;
		return this;
	}

	public Query setStart(Integer start) {
		this.start = start;
		return this;
	}

	public Query setEnd(Integer end) {
		this.end = end;
		return this;
	}

	Map<String, Object> getParams() {
		return this.params;
	}

	private boolean isPager() {
		return ((this.pageNo != null) && (this.pageSize != null));
	}

	private boolean isInterval() {
		return ((this.start != null) && (this.end != null));
	}

	public void setSafeCheck(boolean safeCheck) {
		this.safeCheck = safeCheck;
	}

	String getSql() {
		if (this.safeCheck && !SqlUtil.isSafeSql(this.sql)) {
			throw new SqlInjectionException("sql.injection", new Object[] { this.sql });
		}
		String sql = this.sql;
		int i;
		if (isPager()) {
			i = (this.pageNo.intValue() - 1) * this.pageSize.intValue();
			int j = this.pageSize.intValue();
			sql = this.sqlLimitFactory.getLimitedSql(this.sql, i, j);
		} else if (isInterval()) {
			i = this.end.intValue() - this.start.intValue();
			sql = this.sqlLimitFactory.getLimitedSql(this.sql, this.start.intValue(), i);
		}
		return sql;
	}
}
